package com.smart.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.smart.web.ClientContextHolder;

/**
 * 客户端上下文过滤器
 * 
 * 该类主要作用是侦测每次客户端请求时客户端环境, 包括客户端浏览器类型, IP地址等, 以便于后续线程处理; 
 * @author Sunxin
 *
 */
public class ClientContextFilter implements Filter{

	private static final String HEADER_USER_AGENT = "user-agent";
	private static final String KEYWORD_MOBILE = "mobile";
	private static final String KEYWORD_IPAD = "ipad";
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		if(isMobileDevice(request)){
			ClientContextHolder.setDeviceType("mobile");
		}
		else{
			ClientContextHolder.setDeviceType("non_mobile");
		}
		String ip = getIp(request);
		ClientContextHolder.setIp(ip);
		
		request.getSession().setAttribute("clientIp", ip);
		chain.doFilter(req, res);
		ClientContextHolder.clean();
	}

	@Override
	public void destroy() {
		
	}
	
	protected boolean isMobileDevice(HttpServletRequest request){
		String ua = request.getHeader(HEADER_USER_AGENT).toLowerCase();
		if(ua.indexOf(KEYWORD_MOBILE)!=-1 && ua.indexOf(KEYWORD_IPAD)==-1){
			return true;
		}
		return false;
	}
	
	// get the real IP address under complicated network conditions 
	protected String getIp(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

}
